﻿using System;
using System.Linq;
using System.Transactions;
using yiCommerce.Core;
using yiCommerce.Core.Data;
using yiCommerce.Core.Domain.Customers;
using yiCommerce.Core.Domain.Shops;
using yiCommerce.Service.Messages;
using yiCommerce.Service.Securitys;

namespace yiCommerce.Service.Customers
{
    public class CustomerRegistrationService : ICustomerRegistrationService
    {
        private ICustomerService _customerService;
        private IEncryptionService _encryptionService;
        private IRepository<Shop> _shopRepository;
        private IMessageService _messageService;
        public CustomerRegistrationService(ICustomerService customerService, IEncryptionService encryptionService, IRepository<Shop> shopRepository, IMessageService messageService)
        {
            _customerService = customerService;
            _encryptionService = encryptionService;
            _shopRepository = shopRepository;
            _messageService = messageService;
        }

        public bool ValidateCustomer(string usernameOrEmail, string password)
        {
            Customer customer = _customerService.GetCustomerByEmail(usernameOrEmail);

            if (customer == null || customer.Deleted || !customer.Active)
                return false;

            if (!customer.IsRegistered())
                return false;

            var pwd = _encryptionService.CreatePasswordHash(password, ConstInfo.PasswordSalt, ConstInfo.PasswordFormat);

            bool isValid = pwd == customer.Password;

          

            return isValid;
        }

        public CustomerRegistrationResult RegisterCustomer(CustomerRegistrationRequest request)
        {
            if (request == null)
                throw new ArgumentNullException("request");

            if (request.CustomerId == 0)
                throw new ArgumentException("Can't load current customer");


            var result = new CustomerRegistrationResult();
            if (String.IsNullOrEmpty(request.Email))
            {
                result.AddError("email is empty");
                return result;
            }

            if (!CommonHelper.IsValidEmail(request.Email))
            {
                result.AddError("email wrong format");
                return result;
            }

            if (String.IsNullOrWhiteSpace(request.Password))
            {
                result.AddError("password is empty");
                return result;
            }

            if (String.IsNullOrWhiteSpace(request.UserName))
            {
                result.AddError("username is empty");
                return result;
            }
            //validate unique user
            if (_customerService.GetCustomerByEmail(request.Email) != null)
            {
                result.AddError("Email Already Exists");
                return result;
            }

            if (_customerService.GetCustomerByUserName(request.UserName) != null)
            {
                result.AddError("Username Already Exists");
                return result;
            }

            //at this point request is valid
            var customer = _customerService.GetCustomerById(request.CustomerId);
            customer.Username = request.UserName;
            customer.Email = request.Email;
            //, "aabbcc", "SHA1")
            customer.Password = _encryptionService.CreatePasswordHash(request.Password, "aabbcc","SHA1");
            customer.Active = true;
            //add to 'Registered' role
            var registeredRole = _customerService.GetCustomerRoleBySystemName(SystemCustomerRoleNames.Registered);
            if (registeredRole == null)
                throw new Exception("'Registered' role not existed");
            customer.CustomerRoles.Add(registeredRole);
            //remove from 'Guests' role
            var guestRole = customer.CustomerRoles.FirstOrDefault(cr => cr.SystemName == SystemCustomerRoleNames.Guests);
            if (guestRole != null)
                customer.CustomerRoles.Remove(guestRole);


            try
            {
                using (var scope = new TransactionScope())
                {
                    
                    var shop = CreateShop(customer);

                    customer.ShopId = shop.Id;

                    _customerService.UpdateCustomer(customer);
                    scope.Complete();
                }

            }
            catch (Exception e)
            {
                result.AddError(_messageService.GetResourceValue("RegistFailed",0));
                return result;
            }
            return result;

        }

        private Shop CreateShop(Customer customer)
        {
            var shop = new Shop()
                {
                    ShopName = "",
                    CustomerId = customer.Id
                };
            _shopRepository.Insert(shop);
            return shop;
        }

        public PasswordChangeResult ChangePassword(ChangePasswordRequest request)
        {
            throw new System.NotImplementedException();
        }
    }
}